package com.anniljing.kotlionlearn.Basic.coroutine

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.runBlocking

fun main() {
//    testBasicFlow()
//    testFlowExcept()
    testExchangeScope()
}

/**
 * 基本的flow操作
 */
fun testBasicFlow() {
    runBlocking {
        flow {
            emit(1)
            emit(2)
            emit(3)
            emit(4)
        }.filter {
            it > 2
        }.map {
            it * 2
        }.take(2).collect {
            println(it)
        }
        println("-----------------------------------------------")
        flowOf(1, 2, 3, 4, 5).collect {
            println(it)
        }
    }
}

/**
 * 捕获异常
 * catch只能捕获上游的异常
 */
fun testFlowExcept() {
    runBlocking {
        val flow = flow {
            emit(1)
            emit(2)
            throw IllegalStateException()
            emit(3)
        }

        flow.map {
            it * 2
        }.catch {
            println("catch:$it")
        }.collect {
            println(it)
        }
    }
}

/**
 * flowOn控制其上游的运行环境
 * Dispatchers.Default
 * Dispatchers.IO
 * Dispatchers.Main
 * Dispatchers.Unconfined
 */
fun testExchangeScope() {
    runBlocking {
        val flow = flow {
            emit(2)
            println("emit:${Thread.currentThread().name}")
        }
            .filter {
                println("filter:${Thread.currentThread().name}")
                it > 1
            }.map {
                println("map:${Thread.currentThread().name}")
                it * 2
            }.flowOn(Dispatchers.Unconfined).collect {
                println("collect:${Thread.currentThread().name}")
                println(it)
            }
    }
}

fun testFlowLaunchIn(){
    runBlocking {

        val flow=flow{
            emit(1)
        }
        flow.filter { it>0 }.map { it*2 }
        flow.flowOn(Dispatchers.IO).onEach {
            println(it)
        }
       flow.collect {
           println(it)
       }
    }
}